package speech.tag;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import edu.stanford.nlp.ling.HasWord;
import edu.stanford.nlp.ling.TaggedWord;
import edu.stanford.nlp.tagger.maxent.MaxentTagger;

public class PosTagger {

	MaxentTagger tagger;
	Stemmer stemmer;

	Set<String> stopWords = new HashSet<String>();
	Set<String> frequentWords = new HashSet<String>();

	Map<String, ArrayList<String>> tagFreqWord = new HashMap<String, ArrayList<String>>();
	Map<String, Integer> thresholds = new HashMap<String, Integer>();

	public PosTagger(String taggerModel) {
		try {
			tagger = new MaxentTagger(taggerModel);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		stemmer = new Stemmer();
		setStopWords();
	}

	public void posTagUtterances(String inputPath, String outputPath,
			String saTag) throws IOException {
		List<ArrayList<? extends HasWord>> sentences = MaxentTagger
				.tokenizeText(new BufferedReader(new FileReader(inputPath)));

		FileWriter outFile = new FileWriter(outputPath);
		PrintWriter out = new PrintWriter(outFile);

		for (ArrayList<? extends HasWord> sentence : sentences) {
			ArrayList<TaggedWord> tSentence = tagger.tagSentence(sentence);
			for (TaggedWord tw : tSentence) {
				if (tw.word().equals("?")) {
					out.print(tw.word());
					continue;
				}

				stemmer.add(tw.word().toCharArray(), tw.word().length());
				stemmer.stem();
				String word = stemmer.toString();

				if (tagFreqWord.get(saTag).contains(word)) {
					out.print(word + " ");
				} else {
					if (!tw.tag().equals("."))
						out.print(tw.tag() + " ");
				}
			}
			out.println();
		}
		out.close();
	}

	public Map<String,Integer> computeFrequentWords(boolean calcThresholds, String trainingFolder, double modifier) {

		File folder = new File(trainingFolder);// + File.separatorChar + "stemmed");

		File files[] = folder.listFiles(new FileFilter() {

			@Override
			public boolean accept(File filePath) {
				return filePath.getName().endsWith("fr");
			}
		});

		for (File f : files) {
			try {
				String tag = f.getName().substring(0, f.getName().indexOf('.'));

				tagFreqWord.put(tag, new ArrayList<String>());
				//thresholds.put(tag, 3);

				BufferedReader br = new BufferedReader(new FileReader(f));

				String line;
				int counter = 0;
				while ((line = br.readLine()) != null) {
					String keyword[] = line.split("\t");
					counter++;

					if (!calcThresholds) {
						if (//!stopWords.contains(keyword[0])
								counter < thresholds.get(tag) * modifier) {
							// && Double.parseDouble(keyword[1]) >
							// thresholds.get(f.getName()))
							// frequentWords.add(keyword[0]);
							tagFreqWord.get(tag).add(keyword[0]);
						}
					}
				}
				
				if (calcThresholds) thresholds.put(tag, counter);
				
//				System.out.println(">>> Freq words for " + tag + " with freq #" + thresholds.get(tag) + ": " + tagFreqWord.get(tag));

				// System.out.println(frequentWords);
			} catch (FileNotFoundException e) {
				System.out.println("File not found.");
				e.printStackTrace();
			} catch (IOException e) {
				System.out.println("IO Exception");
				e.printStackTrace();
			}			
		}
		
		return thresholds;
	}

	public static void posTagTrainingFolder(PosTagger posTagger,
			String folderName) throws IOException {

		String allInPath = folderName + File.separatorChar + "all"
				+ File.separatorChar + "raw";
		String genInPath = folderName + File.separatorChar + "general"
				+ File.separatorChar + "raw";
		String allOutPath = folderName + File.separatorChar + "all"
				+ File.separatorChar + "postagged";
		String genOutPath = folderName + File.separatorChar + "general"
				+ File.separatorChar + "postagged";

		File all = new File(allInPath);
		File gen = new File(genInPath);

		File allFiles[] = all.listFiles();
		File genFiles[] = gen.listFiles();

		for (File f : allFiles)
			posTagger.posTagUtterances(allInPath + File.separatorChar
					+ f.getName(), allOutPath + File.separatorChar
					+ f.getName(), f.getName());

		for (File f : genFiles)
			posTagger.posTagUtterances(genInPath + File.separatorChar
					+ f.getName(), genOutPath + File.separatorChar
					+ f.getName(), f.getName());

	}

	private void setStopWords() {
		Stemmer stemmer = new Stemmer();

		try {
			BufferedReader br = new BufferedReader(new FileReader("stopwords"));
			String line;
			while ((line = br.readLine()) != null) {
				line.trim();
				stemmer.add(line.toCharArray(), line.length());
				stemmer.stem();
				stopWords.add(stemmer.toString());
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
